package com.gutai.admin.service.impl;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheConfig;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.data.domain.Sort;
import org.springframework.data.domain.Sort.Direction;
import org.springframework.stereotype.Service;

import com.gutai.admin.common.entity.dto.GoodsWithMutilCategorylDto;
import com.gutai.admin.common.util.IdGeneratorUtil;
import com.gutai.admin.dao.IGoodsDao;
import com.gutai.admin.dao.IProductDao;
import com.gutai.admin.entity.Category;
import com.gutai.admin.entity.Goods;
import com.gutai.admin.service.ICategoryService;
import com.gutai.admin.service.IGoodsService;

/**
 * 
 * 描述：
 * 
 * <pre>
 * HISTORY
 * ****************************************************************************
 *  ID    DATE            PERSON            REASON
 *  1     2018年11月7日         YC           Create
 * ****************************************************************************
 * </pre>
 * 
 * @author YC
 * @version 1.0
 */
@Service
@CacheConfig(cacheNames = "goods")
public class GoodsService implements IGoodsService{

    /**
     * goods desc only with img.
     */
    private final static  String goodDescImgFormat = "<p><img src=\"%s\" " + "_src=\"%s\" style=\"\"/></p>";
    /**
     * good desc end of the text.
     */
    private final static  String goodDescEnd = "<p><br/></p>";
    
    @Autowired
    private IGoodsDao goodsDao;
    @Autowired
    private ICategoryService categoryService;
    @Autowired
    private IProductDao productDao;
    @Autowired
    private IGoodsService goodsService; // 注入自己，内部调用使用缓存

    @Override
    @Cacheable(unless = "#result == null || #result.size()==0")
    public List<Goods> getAll() { //unless = "#result == null || #result.size()==0"
        Sort sort = new Sort(Direction.DESC, "createTime");
        return goodsDao.findAll(sort);
//        List<Goods> goodList = new ArrayList<>();
//        Goods good1 = new Goods();
//        good1.setId(100);
//        good1.setName("good1");
//        goodList.add(good1);
//        Goods good2 = new Goods();
//        good2.setId(101);
//        good2.setName("good2");
//        goodList.add(good2);
//        return goodList;
    }

    @Override
    public List<GoodsWithMutilCategorylDto> getList(String goodsName) {
        List<Goods> goodsList = null;
        if (StringUtils.isNotBlank(goodsName)) {
            goodsList = findByName(goodsName);
        } else {
            goodsList = goodsService.getAll();
        }
        List<Category> categorys = categoryService.getAll();
        List<GoodsWithMutilCategorylDto> goodDtos = new ArrayList<>();
        for (Goods good : goodsList) {
            GoodsWithMutilCategorylDto dto = new GoodsWithMutilCategorylDto();
            BeanUtils.copyProperties(good, dto);
            dto.setCategoryIds(createCategoryCascader(categorys, good.getCategoryId()));
            dto.setGoodsDesc(unpackGoodsDesc(good.getGoodsDesc()));
            goodDtos.add(dto);
        }
        return goodDtos;
    }
    
    @Override
    public List<Goods> findByName(String goodsName){
//      return goodsDao.findByName(goodsName);
        return goodsService.getAll().stream()
                .filter(goods -> goods.getName().indexOf(goodsName) >= 0)
                .collect(Collectors.toList());
    }
    /**
     * 创建级联的类别ID
     * 
     * @param categorys
     * @param categoryId
     * @return
     * @author YC-2018年12月22日
     */
    private List<Integer> createCategoryCascader(List<Category> categorys, Integer categoryId){
        List<Integer> cascaderList = new ArrayList<>();
        cascaderList.add(categoryId);
        Integer parentId = findParentId(categorys, categoryId);
        while (parentId != null && parentId != 0) {
            cascaderList.add(0, parentId);
            parentId = findParentId(categorys, parentId);
        }
        return cascaderList;
    }
    
    /**
     * 根据类别ID查询父类ID
     * 
     * @param categorys
     * @param id
     * @return
     * @author YC-2018年12月22日
     */
    private Integer findParentId(List<Category> categorys, Integer id){
        if (!categorys.isEmpty()){
            Category category =categorys.stream().filter(item -> id.equals(item.getId())).findFirst().orElse(null);
            if (category != null){
                return category.getParentId();
            }
        }
        return null;
    }

    @Override
    // @CachePut(cacheNames = "goods")
    @CacheEvict(allEntries = true)
    public void add(Goods entity) {
        entity.setId(IdGeneratorUtil.generate());
        String descString = entity.getGoodsDesc();

        List<String> descImgs = Arrays.asList(descString.split(","));
        entity.setGoodsDesc(generateGoodsDesc(descImgs));
        goodsDao.save(entity);

//
//        Map<String, Object> condsMap = new HashMap<>();
//        condsMap.put("name", entity.getName());
//        List<Goods> entityAddeds = goodsDao.queryByConds(Goods.class, condsMap);
//
//        Goods entityAdded = entityAddeds.get(0);
//        Product product = new Product();
//        product.setGoodsId(entityAdded.getId());
//        product.setGoodsNumber(entity.getGoodsNumber());
//        product.setRetailPrice(entity.getRetailPrice());
//        product.setGoodSn(String.valueOf(entityAdded.getId()));
//        productDao.add(product);
//        condsMap = new HashMap<>();
//        condsMap.put("goods_id", entityAdded.getId());
//        List<Product> products = productDao.queryByConds(Product.class, condsMap);
//        product = products.get(0);
//
//        entity.setId(product.getGoodsId());
//        entity.setGoodsSn(product.getGoodsSn());
//        entity.setPrimaryProductId(product.getId());
//        return goodsDao.update(entity);
    }
    
    /**
    *
    * @param descImgs list of desc img url
    * @return
    */
    private String generateGoodsDesc(List<String> descImgs) {
        StringBuilder stringBuilder = new StringBuilder();
        for (String descImg : descImgs) {
            String formatDesImg = String.format(goodDescImgFormat, descImg, descImg);
            stringBuilder.append(formatDesImg);
        }
        stringBuilder.append(goodDescEnd);
        return stringBuilder.toString();
    }

    /**
     * 根据格式规则获取多张描述图地址
     * 
     * @param descImgs
     * @return
     * @author YC-2019年4月2日
     */
    private String unpackGoodsDesc(String descImgs) {
        List<String> imgs = Arrays.asList(descImgs.split("</p>")).stream()
                .filter(img -> img.indexOf("src=") > 0)
                .map(img -> img.substring(img.indexOf("src=") + 5, img.indexOf("_src=") - 2))
                .collect(Collectors.toList());
        return imgs.stream().collect(Collectors.joining(","));
    }

    @Override
    @CacheEvict(allEntries = true)
    public void update(Goods entity) {
        String descString = entity.getGoodsDesc();
        List<String> descImgs = Arrays.asList(descString.split(","));
        entity.setGoodsDesc(generateGoodsDesc(descImgs));
        goodsDao.saveAndFlush(entity);
    }

    @Override
    @CacheEvict(allEntries = true)
    public void delete(int id) {
        goodsDao.deleteById(id);
    }

    @Override
    public Goods findById(int id) {
        return goodsDao.findById(id);
    }
}
